package services

import (
	"errors"

	"github.com/cynhard/ticket-system/internal/auth"
	"github.com/cynhard/ticket-system/internal/models"
	"gorm.io/gorm"
)

// UserService 用户服务接口
type UserService interface {
	Register(username, password, email, realName string) (*models.User, error)
	Login(username, password string) (string, *models.User, error)
	GetUserByID(id uint) (*models.User, error)
	ListUsers(page, pageSize int) ([]*models.User, int64, error)
	UpdateUser(id uint, email, realName, role string) (*models.User, error)
	ChangePassword(id uint, oldPassword, newPassword string) error
	DeleteUser(id uint) error
}

// UserServiceImpl 用户服务实现
type UserServiceImpl struct {
	db        *gorm.DB
	jwtSecret string
	jwtExpire int
}

// NewUserService 创建用户服务
func NewUserService(db *gorm.DB, jwtSecret string, jwtExpire int) UserService {
	return &UserServiceImpl{
		db:        db,
		jwtSecret: jwtSecret,
		jwtExpire: jwtExpire,
	}
}

// Register 用户注册
func (s *UserServiceImpl) Register(username, password, email, realName string) (*models.User, error) {
	var existingUser models.User
	result := s.db.Where("username = ?", username).First(&existingUser)
	if result.Error == nil {
		return nil, errors.New("用户名已存在")
	}
	if !errors.Is(result.Error, gorm.ErrRecordNotFound) {
		return nil, result.Error
	}

	if email != "" {
		result = s.db.Where("email = ?", email).First(&existingUser)
		if result.Error == nil {
			return nil, errors.New("邮箱已被使用")
		}
		if !errors.Is(result.Error, gorm.ErrRecordNotFound) {
			return nil, result.Error
		}
	}

	// 创建新用户
	user := &models.User{
		Username: username,
		Password: password, // 密码会在保存前自动哈希
		Email:    email,
		RealName: realName,
		Role:     models.RoleUser, // 默认角色
	}

	result = s.db.Create(user)
	if result.Error != nil {
		return nil, result.Error
	}

	return user, nil
}

// Login 用户登录
func (s *UserServiceImpl) Login(username, password string) (string, *models.User, error) {
	var user models.User
	result := s.db.Where("username = ?", username).First(&user)
	if result.Error != nil {
		if errors.Is(result.Error, gorm.ErrRecordNotFound) {
			return "", nil, errors.New("用户不存在")
		}
		return "", nil, result.Error
	}

	// 验证密码
	if !user.CheckPassword(password) {
		return "", nil, errors.New("密码错误")
	}

	// 生成JWT令牌
	token, err := auth.GenerateToken(user.ID, user.Username, user.Role, s.jwtSecret, s.jwtExpire)
	if err != nil {
		return "", nil, err
	}

	return token, &user, nil
}

// GetUserByID 根据ID获取用户
func (s *UserServiceImpl) GetUserByID(id uint) (*models.User, error) {
	var user models.User
	result := s.db.First(&user, id)
	if result.Error != nil {
		return nil, result.Error
	}
	return &user, nil
}

// ListUsers 获取用户列表
func (s *UserServiceImpl) ListUsers(page, pageSize int) ([]*models.User, int64, error) {
	var users []*models.User
	var total int64

	offset := (page - 1) * pageSize

	s.db.Model(&models.User{}).Count(&total)
	result := s.db.Offset(offset).Limit(pageSize).Find(&users)
	if result.Error != nil {
		return nil, 0, result.Error
	}

	return users, total, nil
}

// UpdateUser 更新用户信息
func (s *UserServiceImpl) UpdateUser(id uint, email, realName, role string) (*models.User, error) {
	user, err := s.GetUserByID(id)
	if err != nil {
		return nil, err
	}

	// 如果邮箱变更，需要检查是否被占用
	if email != "" && email != user.Email {
		var existingUser models.User
		result := s.db.Where("email = ? AND id != ?", email, id).First(&existingUser)
		if result.Error == nil {
			return nil, errors.New("邮箱已被使用")
		}
		if !errors.Is(result.Error, gorm.ErrRecordNotFound) {
			return nil, result.Error
		}
		user.Email = email
	}

	if realName != "" {
		user.RealName = realName
	}

	if role != "" {
		user.Role = role
	}

	result := s.db.Save(user)
	if result.Error != nil {
		return nil, result.Error
	}

	return user, nil
}

// ChangePassword 修改密码
func (s *UserServiceImpl) ChangePassword(id uint, oldPassword, newPassword string) error {
	user, err := s.GetUserByID(id)
	if err != nil {
		return err
	}

	// 验证旧密码
	if !user.CheckPassword(oldPassword) {
		return errors.New("旧密码错误")
	}

	// 更新密码
	user.Password = newPassword
	result := s.db.Save(user)
	if result.Error != nil {
		return result.Error
	}

	return nil
}

// DeleteUser 删除用户
func (s *UserServiceImpl) DeleteUser(id uint) error {
	result := s.db.Delete(&models.User{}, id)
	if result.Error != nil {
		return result.Error
	}
	if result.RowsAffected == 0 {
		return errors.New("用户不存在")
	}
	return nil
} 